package training_set;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.util.*;

import weka.classifiers.functions.Logistic;
import weka.core.Attribute;
import weka.core.FastVector;
import weka.core.Instances;
import weka.core.converters.ArffLoader;

public class Pairwise_Model {
	public FastVector fvectors = new FastVector(9);
	public Instances Istraining;
	public Instances Istest;
	public Pairwise_Model(){
		String attribute_names[] = {"name","mesh", "majormesh","journal","cosine","cui","semantics","coldbigram"};
		for(int i=0; i<attribute_names.length; i++)
			fvectors.addElement(new Attribute(attribute_names[i]));
		FastVector fvnominal1 = new FastVector(2);
		fvnominal1.addElement("+1");
		fvnominal1.addElement("-1");
		Attribute classattribute = new Attribute("theclass",fvnominal1);
		fvectors.addElement(classattribute);
	}
	public void ReadTraining(String trainingfile){
		try{
			ArffLoader load = new ArffLoader();
			load.setFile(new File(trainingfile));
			Istraining = load.getDataSet();
			Istraining.setClassIndex(Istraining.numAttributes()-1);
		}catch(IOException e){
			e.printStackTrace();
		}
	}
	public void ReadTest(String testfile){
		try{
			ArffLoader load = new ArffLoader();
			load.setFile(new File(testfile));
			Istest = load.getDataSet();
			Istest.setClassIndex(Istest.numAttributes()-1);
		}catch(IOException e){
			e.printStackTrace();
		}
	}
	public void FilterTraining(String writefile,List<Pair> pairs,boolean positive, int size){
		File f = new File(writefile);
		Logistic model = new Logistic();
		
		try{
			
			OutputStreamWriter write = new OutputStreamWriter(new FileOutputStream(f, false));
			BufferedWriter bw = new BufferedWriter(write);
			model.buildClassifier(Istraining);
			for(int i=0; i<Istraining.numInstances(); i++){
				double result[] = model.distributionForInstance(Istraining.instance(i));
				// result[0]: probability for being positive.
				if(positive && i<pairs.size() && result[0] >=0.99){
					bw.write(pairs.get(i).getPmid1()+"\t"+pairs.get(i).getPmid2());
					bw.newLine();
				}
				if(!positive && i>=size && result[1] >=0.99){
					bw.write(pairs.get(i-size).getPmid1()+"\t"+pairs.get(i-size).getPmid2());
					bw.newLine();
				}
			}
			bw.close();
			
		}catch(IOException e){
			e.printStackTrace();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	public void TrainModel(String writefile,int size){
		File f = new File(writefile);
		Logistic model = new Logistic();
		
		try{
			
			OutputStreamWriter write = new OutputStreamWriter(new FileOutputStream(f, false));
			BufferedWriter bw = new BufferedWriter(write);
			model.buildClassifier(Istraining);
			int j = 0, k=1;
			for(int i=0; i<Istest.numInstances(); i++){
				double result[] = model.distributionForInstance(Istest.instance(i));
				// result[0]: probability for being positive.
				bw.write(String.valueOf(j)+"\t"+String.valueOf(k)+"\t");
				bw.write(String.valueOf(result[0]));
				bw.newLine();
				k++;
				if(k>=size){
					j++;
					k=j+1;
				}
			}
			bw.close();
			if(j!=size-1 || k!=size)
				throw new Exception("Index and results do not match!");
		}catch(IOException e){
			e.printStackTrace();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

}
